#include "Session.h"
#include "../log.h"
#include "global.h"
#include "ChatServer.h"
#include "Logic.h"
#include "../Singleton.h"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <mutex>

Session::Session(boost::asio::io_context& io_context, Server* server)
:_socket(io_context)
,_server(server)
,_b_closed(false)
,_b_head_parsed(false)
,_read_buf(new char[MSG_MAX_LENGTH])
{
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    _sessionId = boost::uuids::to_string(uuid);

    _head_node = std::make_shared<HeadNode>();
}

void Session::Start()
{
    memset(_read_buf.get(), 0, MSG_MAX_LENGTH);
    _socket.async_read_some(
        boost::asio::buffer(_read_buf.get(), MSG_MAX_LENGTH),
        [this, ptr = shared_from_this()](const boost::system::error_code& ec, size_t len) {
            _HandleRead(ec, len, ptr);
        });
}

void Session::Send(const char* msg, size_t len, uint32_t msg_id)
{
    std::lock_guard<std::mutex> lock(_send_lock);
    auto size = _send_queue.size();
    if(size > MAX_SEND_QUEUE)    //控制发送队列最大长度
    {
        log_error("Session::Send, send queue is full, size: {}", size);
        return;
    }

    _send_queue.push(std::make_shared<SendNode>(msg, len, msg_id));
    if(size > 0) //发送队列不为空，不需要再次调用发送回调函数
    {
        return;
    }
    auto& msg_node = _send_queue.front();
    boost::asio::async_write(_socket, boost::asio::buffer(msg_node->_data.get(), msg_node->_total_len),
        [this, ptr = shared_from_this()](const boost::system::error_code& ec, size_t /*length*/) {
            _HandleWrite(ec, ptr);
        });
}


void Session::_HandleWrite(const boost::system::error_code& ec, std::shared_ptr<Session> self_ptr)
{
    if(ec)
    {
        _server->DeleteSession(_sessionId);
        _Close();
        log_error("Session::_HandleWrite error, code: {}, message: {}", ec.value(), ec.message());
        return;
    }

    try
    {
        std::lock_guard<std::mutex> lock(_send_lock);
        _send_queue.pop();
        if(_send_queue.empty())
        {
            return;
        }
        auto& msg_node = _send_queue.front();
        boost::asio::async_write(_socket, boost::asio::buffer(msg_node->_data.get(), msg_node->_total_len),
            [this, ptr = shared_from_this()](const boost::system::error_code& ec, size_t /*length*/) {
                _HandleWrite(ec, ptr);
            });
    }
    catch (const std::exception& e)
    {
        _server->DeleteSession(_sessionId);
        _Close();
        log_error("Session::_HandleWrite exception: {}", e.what());
        return;
    }
}

void Session::_HandleRead(const boost::system::error_code& ec, size_t len, std::shared_ptr<Session> self_ptr)
{
    if (ec) 
    {
        _server->DeleteSession(_sessionId);
        log_error("Session::_HandleRead error, code: {}, message: {}", ec.value(), ec.message());
        return;
    }

    size_t offset = 0;

    while(len > 0)
    {
        // --------- Step 1: 解析头部 ---------
        if(!_b_head_parsed)
        {
            size_t need = HEAD_LENGTH - _head_node->_cur_len;
            size_t to_copy = std::min(need, len);

            memcpy(_head_node->_data.get() + _head_node->_cur_len, 
                _read_buf.get() + offset, to_copy);

            _head_node->_cur_len += to_copy;
            offset += to_copy;
            len -= to_copy;

            if(_head_node->_cur_len < HEAD_LENGTH)
            {
                break; // 头部还没接收完，等待下一次接收
            }

            // 头部接收完毕，解析头部信息
            auto ret = _head_node->GetHeatInfo();
            if(ret != 0)
            {
                _server->DeleteSession(_sessionId);
                log_error("Session::_HandleRead error, code: {}", ret);
                return;
            }

            _recv_node = std::make_shared<RecvNode>(_head_node->GetMsgLen(), _head_node->GetMsgId());
            _b_head_parsed = true;
        }

        // --------- Step 2: 解析消息体 ---------
        size_t need = _recv_node->_total_len - _recv_node->_cur_len;
        size_t to_copy = std::min(need, len);

        memcpy(_recv_node->_data.get() + _recv_node->_cur_len,
            _read_buf.get() + offset, to_copy);

        _recv_node->_cur_len += to_copy;
        offset += to_copy;
        len -= to_copy;

        if(_recv_node->_cur_len < _recv_node->_total_len)
        {
            break; // 消息体还没接收完，等待下一次接收
        }

        // --------- Step 3: 完整消息，交给逻辑层 ---------
        Singleton<Logic>::GetInstance()->PostMsgToQueue(std::make_shared<LogicNode>(shared_from_this(), _recv_node));

        // 重置状态机，准备下一条消息
        _head_node->Clear();
        _recv_node.reset();
        _b_head_parsed = false;
    }

    // 继续收数据
    memset(_read_buf.get(), 0, MSG_MAX_LENGTH);
    _socket.async_read_some(
        boost::asio::buffer(_read_buf.get(), MSG_MAX_LENGTH),
        [this, ptr = shared_from_this()](const boost::system::error_code& ec, size_t len) {
            _HandleRead(ec, len, ptr);
        });
}

void Session::_Close()
{
    _socket.close();
    _b_closed = true;
}